﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using ControleRepresentante.Logic.Models;
using ControleRepresentante.Logic.Repositories;
using ControleRepresentante.Logic.Repositories.SearchExtensions;
using ControleRepresentante.Logic.Statistics;
using WebSite.Controllers.ControllerExtensions;
using WebSite.ViewModels.DetailsViewModels;
using WebSite.ViewModels.EditViewModels;
using WebSite.ViewModels.IndexViewModels;
using Attribute = ControleRepresentante.Logic.Models.Attribute;

namespace WebSite.Controllers
{
    public class RelatorioVisitaController : AttributeHolderControllerBase<IRelatorioVisitaRepository, RelatorioVisita, StatisticsBase>
    {
        public RelatorioVisitaController(IRepositoryProvider repositoryProvider, ISessionConfiguration sessionConfiguration, IControllerExtensionProvider controllerExtensionProvider)
            : base(repositoryProvider, sessionConfiguration, controllerExtensionProvider)
        {
        }

        protected override AttributeHolderDetailsViewModel GetAttributeHolderDetailsViewModel(RelatorioVisita model)
        {
            return new RelatorioVisitaDetailsViewModel(
                HasPermission(ControleRepresentante.Logic.Models.Area.Clientes, Operacao.View),
                HasPermission(ControleRepresentante.Logic.Models.Area.Vendedores, Operacao.View));
        }

        protected override AttributeHolderEditViewModel GetEditViewModel()
        {
            Dictionary<Guid, string> clientes = RepositoryProvider.GetRepository<IClienteRepository>().GetModelNames();
            Dictionary<Guid, string> vendedores = RepositoryProvider.GetRepository<IVendedorRepository>().GetModelNames();
            return new RelatorioVisitaEditViewModel(clientes, vendedores);
        }

        protected override IAttributeHolderIndexViewModel GetAttributeHolderIndexViewModel(StatisticsBase statistics)
        {
            return new RelatorioVisitaIndexViewModel(
                HasPermission(ControleRepresentante.Logic.Models.Area.Clientes, Operacao.View),
                HasPermission(ControleRepresentante.Logic.Models.Area.Vendedores, Operacao.View));
        }

        protected override void RegisterIndexColumns(ControleRepresentante.Logic.IIndexColumnsProvider indexColumnsProvider)
        {
            base.RegisterIndexColumns(indexColumnsProvider);

            indexColumnsProvider.SetDefaultColumns(
                indexColumnsProvider.RegisterColumn("Data", RelatorioVisitaIndexColumns.Data, true),
                indexColumnsProvider.RegisterColumn("Cliente", RelatorioVisitaIndexColumns.Cliente),
                indexColumnsProvider.RegisterColumn("Vendedor", RelatorioVisitaIndexColumns.Vendedor));
            indexColumnsProvider.RegisterColumn("Observação", RelatorioVisitaIndexColumns.Observacao);
        }

        public ActionResult Search(DateTime? de, DateTime? ate, string cliente, string vendedorIds, string observacao, FormCollection formCollection)
        {
            EnsureHasPermission(Operacao.View);

            formCollection.Add(Request.QueryString);

            IAttributeRepository attributeRepository = RepositoryProvider.GetRepository<IAttributeRepository>();
            Dictionary<Attribute, string> attributeMap = GetAttributeMap(attributeRepository, formCollection);

            Dictionary<Guid, string> vendedores = ParseIds<IVendedorRepository, Vendedor, StatisticsBase>(vendedorIds, x => x.Nome);
            ISearchExtension[] searchExtensions = GetSearchExtensions(formCollection);

            StatisticsBase statistics;
            IEnumerable<RelatorioVisita> models = Repository.GetModels(de, ate, cliente, vendedores.Keys, observacao, attributeMap, searchExtensions, out statistics, GetPage());

            return Index(models, statistics, formCollection, x =>
                                                                           {
                                                                               RelatorioVisitaIndexViewModel relatorioVisitaIndexViewModel = (RelatorioVisitaIndexViewModel)x;
                                                                               relatorioVisitaIndexViewModel.VendedorBusca = vendedores;
                                                                               relatorioVisitaIndexViewModel.AteBuscaValue = ate;
                                                                               relatorioVisitaIndexViewModel.DeBuscaValue = de;
                                                                               relatorioVisitaIndexViewModel.ClienteBuscaValue = cliente;
                                                                               SetAttributeSearchValues(relatorioVisitaIndexViewModel, attributeMap);
                                                                               relatorioVisitaIndexViewModel.VendedorBuscaValue = vendedorIds;
                                                                               relatorioVisitaIndexViewModel.ClienteBuscaValue = cliente;
                                                                               relatorioVisitaIndexViewModel.ObservacaoBuscaValue = observacao;
                                                                           });
        }

        protected override AttributeType AttributeType
        {
            get { return AttributeType.RelatorioVisita; }
        }

        protected override Area? Area
        {
            get
            {
                return ControleRepresentante.Logic.Models.Area.RelatorioVisita;
            }
        }

        [HttpPost]
        public ActionResult Create(DateTime? data, Guid clienteId, Guid vendedorId, string observacao, FormCollection formCollection = null)
        {
            EnsureHasPermission(Operacao.Create);
            if (TryUpdateRelatorioVisita(data, clienteId, vendedorId, observacao, formCollection))
            {
                Repository.AddModel(Model);
                RelatorioVisita relatorioVisita = Model;
                Model = null;
                return RedirectToAction("Details", relatorioVisita.Id);
            }
            return Create(false);
        }

        [HttpPost]
        public ActionResult Edit(DateTime? data, Guid clienteId, Guid vendedorId, string observacao, FormCollection formCollection = null)
        {
            EnsureHasPermission(Operacao.Update);
            if (TryUpdateRelatorioVisita(data, clienteId, vendedorId, observacao, formCollection))
            {
                Repository.UpdateModel(Model);
                Guid relatorioVisitaId = Model.Id;
                Model = null;
                return RedirectToAction("Details", relatorioVisitaId);
            }
            return Edit();
        }

        private bool TryUpdateRelatorioVisita(DateTime? data, Guid clienteId, Guid vendedorId, string observacao, FormCollection formCollection)
        {
            Model.Cliente = RepositoryProvider.GetRepository<IClienteRepository>().GetModelById(clienteId);
            Model.Vendedor = RepositoryProvider.GetRepository<IVendedorRepository>().GetModelById(vendedorId);
            if (data.HasValue)
            {
                Model.Data = data.Value;
            }
            Model.Observacao = observacao;

            UpdateAttributesToModel(formCollection);

            ModelState.Clear();
            if (!data.HasValue)
            {
                ModelState.AddModelError("Data", "*");
            }
            if (String.IsNullOrWhiteSpace(observacao))
            {
                ModelState.AddModelError("Observacao", "*");
            }
            ExtensionsUpdateModel(formCollection);
            return ModelState.IsValid;
        }
    }
}
